package com.cc.blog.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cc.blog.admin.domain.dto.AddTagReqDTO;
import com.cc.blog.admin.domain.dto.DeleteTagReqDTO;
import com.cc.blog.admin.domain.dto.FindTagPageListReqDTO;
import com.cc.blog.admin.domain.dto.SearchTagsReqDTO;
import com.cc.blog.admin.domain.vo.FindTagPageListRspVO;
import com.cc.blog.admin.mapper.ArticleTagRelMapper;
import com.cc.blog.admin.mapper.TagMapper;
import com.cc.blog.admin.model.ArticleTagRelDO;
import com.cc.blog.admin.model.TagDO;
import com.cc.blog.admin.service.AdminTagService;
import com.cc.blog.common.enums.CodeEnum;
import com.cc.blog.common.exception.BusinessException;
import com.cc.blog.common.model.SelectRspVO;
import com.cc.blog.common.utils.PageResult;
import com.cc.blog.common.utils.Result;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author cc
 * @Date 2024/7/10 17:09
 */
@Service
@Slf4j
@AllArgsConstructor
public class AdminTagServiceImpl extends ServiceImpl<TagMapper, TagDO> implements AdminTagService {

    private final ArticleTagRelMapper articleTagRelMapper;

    @Override
    public Result addTags(AddTagReqDTO addTagReqDTO) {
        // vo 转 do
        List<TagDO> tagDOS = addTagReqDTO.getTags().stream()
                .map(tagName -> TagDO.builder()
                        .name(tagName.trim()) // 去掉前后空格
                        .createTime(LocalDateTime.now())
                        .updateTime(LocalDateTime.now())
                        .build())
                .collect(Collectors.toList());
        // 批量插入
        try {
            saveBatch(tagDOS);
        } catch (Exception e) {
            log.warn("该标签已存在", e);
        }
        return Result.success();
    }

    @Override
    public PageResult findTagPageList(FindTagPageListReqDTO findTagPageListReqDTO) {
        // 分页对象
        Page<TagDO> page = new Page<>(findTagPageListReqDTO.getCurrent(), findTagPageListReqDTO.getSize());
        // 条件参数
        String name = findTagPageListReqDTO.getName();
        LocalDate startDate = findTagPageListReqDTO.getStartDate();
        LocalDate endDate = findTagPageListReqDTO.getEndDate();
        // 构建查询条件
        LambdaQueryWrapper<TagDO> wrapper = Wrappers.<TagDO>lambdaQuery()
                .like(Objects.nonNull(name), TagDO::getName, name)
                .ge(Objects.nonNull(startDate), TagDO::getCreateTime, startDate)
                .le(Objects.nonNull(endDate), TagDO::getCreateTime, endDate)
                .orderByDesc(TagDO::getCreateTime);
        // 分页查询
        Page<TagDO> pageData = page(page, wrapper);
        List<TagDO> records = pageData.getRecords();
        // do 转 vo
        List<FindTagPageListRspVO> vos = null;
        if (!CollectionUtils.isEmpty(records)) {
            vos = records.stream().map(tagDO -> FindTagPageListRspVO.builder()
                    .id(tagDO.getId())
                    .name(tagDO.getName())
                    .articlesTotal(tagDO.getArticlesTotal())
                    .createTime(tagDO.getCreateTime())
                    .build()).collect(Collectors.toList());
        }
        return PageResult.success(page, vos);
    }

    @Override
    public Result deleteTag(DeleteTagReqDTO deleteTagReqDTO) {
        // 标签 ID
        Long tagId = deleteTagReqDTO.getId();
        // 校验该标签下是否有关联的文章，若有，则不允许删除，提示用户需要先删除标签下的文章
        ArticleTagRelDO articleTagRelDO = articleTagRelMapper.selectOne(Wrappers.<ArticleTagRelDO>lambdaQuery()
                .eq(ArticleTagRelDO::getTagId, tagId)
                .last("LIMIT 1"));
        if (Objects.nonNull(articleTagRelDO)) {
            log.warn("==> 此标签下包含文章，无法删除，tagId: {}", tagId);
            throw new BusinessException(CodeEnum.TAG_CAN_NOT_DELETE);
        }
        // 根据标签 ID 删除
        int count = this.baseMapper.deleteById(tagId);
        return count == 1 ? Result.success() : Result.fail(CodeEnum.TAG_NOT_EXISTED);
    }

    @Override
    public Result searchTags(SearchTagsReqDTO searchTagsReqDTO) {
        String key = searchTagsReqDTO.getKey();
        // 执行模糊查询
        List<TagDO> tagDOS = list(Wrappers.<TagDO>lambdaQuery().like(TagDO::getName, key).orderByDesc(TagDO::getCreateTime));
        // do 转 vo
        List<SelectRspVO> vos = null;
        if (!CollectionUtils.isEmpty(tagDOS)) {
            vos = tagDOS.stream()
                    .map(tagDO -> SelectRspVO.builder()
                            .label(tagDO.getName())
                            .value(tagDO.getId())
                            .build())
                    .collect(Collectors.toList());
        }
        return Result.success(vos);
    }

    @Override
    public Result findTagSelectList() {
        // 查询所有标签, Wrappers.emptyWrapper() 表示查询条件为空
        List<TagDO> tagDOS = this.baseMapper.selectList(Wrappers.emptyWrapper());
        // DO 转 VO
        List<SelectRspVO> vos = null;
        if (!CollectionUtils.isEmpty(tagDOS)) {
            vos = tagDOS.stream()
                    .map(tagDO -> SelectRspVO.builder()
                            .label(tagDO.getName())
                            .value(tagDO.getId())
                            .build())
                    .collect(Collectors.toList());
        }
        return Result.success(vos);
    }
}
